#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtGui/QFileDialog>
#include <QtGui/QCheckBox>
#include <QtGui/QVBoxLayout>
#include <QtGui/QComboBox>
#include <QtGui/QFormLayout>
#include "mapviewer/MapViewer.h"

#include "pluginmanager/PluginManager.h"

#include <iostream>


#include "robot/robot.h"
#include "robotmap/robotmap.h"
#include "sensors/Sensor.h"

MainWindow::MainWindow ( QWidget *parent ) :
        QMainWindow ( parent ),
        r ( 0 ), ui ( new Ui::MainWindow ), _mv ( 0 )
{
    ui->setupUi ( this );
    _scale = 100 ;
	
	_time = new QTimer() ;
	_time->setInterval(1000);

    ui->gbSensors->setLayout ( new QVBoxLayout() );
	ui->gbPanelSensors->setLayout ( new QVBoxLayout() );
    QFormLayout* fl = new QFormLayout() ;
    fl->setFormAlignment ( Qt::AlignHCenter | Qt::AlignTop );
    fl->setLabelAlignment ( Qt::AlignVCenter );
    ui->gbTiles->setLayout ( fl );
    ui->gbTiles->layout()->setSizeConstraint ( QLayout::SetMinAndMaxSize );
// 	ui->gbTiles->layout()->maximumSize().setHeight(300);
    ui->saTiles->setWidget ( ui->gbTiles );
	ui->saSensors->setWidget ( ui->gbPanelSensors );
//     ui->gbSensors->layout()->maximumSize().setHeight ( ui->gbSensors->height() );
//     ui->gbSensors->layout()->minimumSize().setHeight ( 10 );
//     ui->gbSensors->layout()->setSizeConstraint ( QLayout::SetMinAndMaxSize );

    connect ( ui->zoomSlider,SIGNAL ( valueChanged ( int ) ), this, SLOT ( zoom ( int ) ) ) ;
    connect ( ui->left, SIGNAL ( clicked() ), this, SLOT ( moveLeft() ) ) ;
    connect ( ui->right, SIGNAL ( clicked() ), this, SLOT ( moveRight() ) ) ;
    connect ( ui->up, SIGNAL ( clicked() ), this, SLOT ( moveUp() ) ) ;
    connect ( ui->down, SIGNAL ( clicked() ), this, SLOT ( moveDown() ) ) ;
//     connect ( ui->actionOuvrir, SIGNAL ( triggered() ), this, SLOT ( openFile() ) ) ;
//     connect ( ui->actionQuitter, SIGNAL ( triggered() ), this, SLOT ( close() ) ) ;
    connect ( ui->btnRobotImage, SIGNAL ( clicked() ), this, SLOT ( chooseRobotImage() ) ) ;
    connect ( ui->btnOpenPlugin, SIGNAL ( clicked() ), this, SLOT ( loadPlugins() ) ) ;
    connect ( ui->btnCreateRobot, SIGNAL ( clicked() ), this, SLOT ( createRobot() ) ) ;
    connect ( ui->btnChooseMap, SIGNAL ( clicked() ), this, SLOT ( chooseMap() ) ) ;
    connect ( ui->btnChooseTile, SIGNAL ( clicked() ), this, SLOT ( chooseTile() ) ) ;
    connect ( ui->btnLoadMap, SIGNAL ( clicked() ), this, SLOT ( loadMap() ) ) ;
    connect ( ui->btnValidMap, SIGNAL ( clicked() ), this, SLOT ( validMap() ) ) ;
    connect (ui->btnShowMap, SIGNAL(clicked()), this, SLOT(showMap())) ;
    connect (ui->btnGo, SIGNAL(clicked()), this, SLOT(truc())) ;
	connect (_time, SIGNAL(timeout()), this, SLOT(gogogo())) ;

    _rm = new RobotMap() ;
    PluginManager::getInstance().setRobotMap(_rm);
}

MainWindow::~MainWindow()
{
    delete ui;
}

// void MainWindow::openFile()
// {
//     QString file = QFileDialog::getOpenFileName ( this, "Open TMX Map", ( QDir::currentPath().toStdString() + "/examples/" ).c_str() ) ;
//     if ( file != "" )
//     {
//         if ( _mv )
//             delete _mv ;
//         _mv = new MapViewer() ;
//         _mv->viewMap ( file.toStdString() );
//         ui->zoomSlider->setValue ( 100 );
//         _scale = 100 ;
// 
//         if ( r )
//             delete r ;
//         std::cout << "ouiiii" << std::endl ;
//         r = new Robot ( "Tutu" ) ;
//         RobotMap* rm = new RobotMap ( _mv, r ) ;
//         r->setRobotMap ( rm );
// 
//         r->setImage ( "/home/aendawyn/projects/I-Wander/robot/Robot-icon.png" );
// 
//         PluginManager::getInstance().loadLibrary ( ( QDir::currentPath().toStdString() + "/sensors/.libs/libsensors.so" ).c_str() ) ;
//         PluginManager::getInstance().setRobot ( r );
//         PluginManager::getInstance().setRobotMap ( rm );
//         Sensor* gps = PluginManager::getInstance().createSensor ( "GPS" ) ;
//         if ( gps )
//             std::cout << "gps créé" << std::endl ;
//         _mv->addRobotImage ( r->image() );
// 
//         std::cout << "GPS position ? " << r->addSensor ( gps ) << std::endl ;
// 
//         if ( r->sensor ( 0 ) != 0 && r->sensor ( 0 )->statusPanel() != 0 )
//         {
//             r->sensor ( 0 )->statusPanel()->setParent ( this ) ;
//             r->sensor ( 0 )->statusPanel()->move ( 5, 175 );
//             r->sensor ( 0 )->statusPanel()->show();
//             std::cout << "panel OK" << std::endl ;
//         }
//     }
// }

void MainWindow::zoom ( int scale )
{
    if ( _mv )
    {
        _mv->scale ( qreal ( scale ) /_scale, qreal ( scale ) /_scale );
        _scale = qreal ( scale ) ;
    }
}

void MainWindow::moveLeft()
{
    r->moveLeft();
}

void MainWindow::moveRight()
{
    r->moveRight();
}

void MainWindow::moveUp()
{
    r->moveUp();
}

void MainWindow::moveDown()
{
    r->moveDown();
}

void MainWindow::chooseRobotImage()
{
    QString file = QFileDialog::getOpenFileName ( this, "Image du robot...", ( QDir::currentPath().toStdString() + "/robot/" ).c_str(), "Images (*.png *.gif *.jpg)" ) ;
    if ( file != "" )
    {
        ui->robotImage->setPixmap ( QPixmap::fromImage ( QImage ( file ) ) );
    }
}

void MainWindow::loadPlugins()
{
    QString file = QFileDialog::getOpenFileName ( this, "Plugin", QDir::currentPath().toStdString().c_str(), "Plugin (*.so)" ) ;
    if ( file != "" )
    {
        PluginManager::getInstance().loadLibrary ( file.toStdString() );
    }
    for ( size_t i = 0 ; i < PluginManager::getInstance().sensors().size() ; i++ )
    {
        QCheckBox* cb = new QCheckBox ( QString ( PluginManager::getInstance().sensors().at ( i ).first.c_str() ) ) ;
        cb->setToolTip ( QString ( PluginManager::getInstance().sensors().at ( i ).second.c_str() ) );
        ui->gbSensors->layout()->addWidget ( cb );
        cb->show();
        std::cout << PluginManager::getInstance().sensors().at ( i ).first << std::endl ;
    }
}

void MainWindow::createRobot()
{
    if ( r )
        delete r ;

    r = new Robot ( ui->robotName->text().toStdString() ) ;
    if ( ui->robotImage->pixmap() )
	{
        r->setImage ( * ( ui->robotImage->pixmap() ) );
		r->image()->scale(0.5,0.5);
	}
    for ( int i = 0 ; i < ui->gbSensors->children().size() ; i++ )
    {
        QCheckBox* cb = dynamic_cast<QCheckBox*> ( ui->gbSensors->children().at ( i ) ) ;
        if ( cb != 0 )
        {
            if ( cb->isChecked() )
            {
                r->addSensor ( PluginManager::getInstance().createSensor ( cb->text().toStdString() ) ) ;
            }
        }
    }
    for ( int i = 0 ; i < ui->gbActuators->children().size() ; i++ )
    {
        QCheckBox* cb = dynamic_cast<QCheckBox*> ( ui->gbActuators->children().at ( i ) ) ;
        if ( cb != 0 )
        {
            if ( cb->isChecked() )
            {
                r->addActuator ( PluginManager::getInstance().createActuator ( cb->text().toStdString() ) ) ;
            }
        }
    }
    std::cout << "Nom : " << r->name() << std::endl ;
    std::cout << "Image : " << ( r->image() == 0 ? "non" : "oui" ) << std::endl ;
    std::cout << "Senseurs : " << r->sensorsCount() << std::endl ;
    std::cout << "Actuateurs : " << r->actuatorsCount() << std::endl ;

    r->setRobotImageZValue(1000);
    _rm->setRobot ( r );
    PluginManager::getInstance().setRobot(r);
}

void MainWindow::chooseMap()
{
    QString file = QFileDialog::getOpenFileName ( this, "Carte", ( QDir::currentPath().toStdString() + "/examples" ).c_str(), "Cartes (*.tmx)" ) ;
    if ( file != "" )
    {
        ui->txtPathMap->setText ( file ) ;
    }
}

void MainWindow::chooseTile()
{
    QString file = QFileDialog::getOpenFileName ( this, "Ressources", ( QDir::currentPath().toStdString() + "/examples" ).c_str(), "Ressources (*.rt)" ) ;
    if ( file != "" )
    {
        ui->txtPathTile->setText ( file ) ;
    }
}

void MainWindow::loadMap()
{
    if ( ui->txtPathMap->text() != "" && ui->txtPathTile->text() != "" )
    {
        ui->txtPathMap->setText ( ui->txtPathMap->text() ) ;
        if ( _mv )
            delete _mv ;
        _mv = new MapViewer() ;
        _mv->viewMap ( ui->txtPathMap->text().toStdString() );

        ui->lblHeight->setText ( QString::number ( _mv->map()->height() ) );
        ui->lblLayers->setText ( QString::number ( _mv->map()->layers().size() ) );
        ui->lblWidth->setText ( QString::number ( _mv->map()->width() ) );
        switch ( _mv->map()->orientation() )
        {
        case ORTHOGONAL :
            ui->lblOrientation->setText ( QString ( "Orthogonale" ) );
            break ;
        case ISOMETRIC :
            ui->lblOrientation->setText ( QString ( "Isométrique" ) );
            break ;
        case HEXAGONAL :
            ui->lblOrientation->setText ( QString ( "Hexagonale" ) );
            break ;
        }

        QFile f ( ui->txtPathTile->text() ) ;
        if ( !f.open ( QIODevice::ReadOnly | QIODevice::Text ) )
        {
            std::cerr << "Unable to open " << ui->txtPathTile->text().toStdString() << std::endl ;
            return ;
        }
        QStringList sl ;
        while ( !f.atEnd() )
        {
            sl.append ( f.readLine().replace ( '\n','\0' ).data() ) ;
            _rm->addRessourceType ( sl.last().toStdString() );
        }

        // Ressources
        std::map<const Tile*, const QPixmap>::const_iterator it ;
        for ( it = _mv->ressources().begin() ; it != _mv->ressources().end() ; it ++ )
        {
            QLabel* image = new QLabel() ;
            image->setPixmap ( it->second ) ;
            QComboBox* cb = new QComboBox() ;
            cb->addItems ( sl ) ;
            ( ( QFormLayout* ) ui->gbTiles->layout() )->addRow ( image, cb );
        }
    }

    _rm->setMapViewer ( _mv ) ;
}

void MainWindow::validMap()
{
    QFormLayout* l = ( QFormLayout* ) ui->gbTiles->layout() ;
    if (l)
        for (int i = 0 ; i < l->count() ; i+=2)
        {
            QLabel* img = (QLabel*) l->itemAt(i)->widget() ;
            QComboBox* cb = (QComboBox*) l->itemAt(i+1)->widget() ;
            if (img && cb)
            {
                _rm->setRessourceMatch(*(img->pixmap()), cb->currentIndex());
            }
        }

    if (r)
    {
        _rm->mapViewer()->addRobotImage(_rm->robot()->image()) ;
		for(int i = 0 ; i < _rm->robot()->sensorsCount() ; i++)
		{
			if(r->sensor(i) && r->sensor ( i )->statusPanel() != 0 )
			{
				r->sensor(i)->setRobotMap(_rm);
				r->sensor(i)->updateDatas();
				ui->gbPanelSensors->layout()->addWidget(r->sensor ( i )->statusPanel());
				r->sensor ( i )->statusPanel()->show();
			}
		}
    }
}

void MainWindow::showMap()
{
    if (_mv)
        _mv->show() ;
	_rm->setRobotPosition(12,1);
}


void MainWindow::gogogo()
{
    _rm->launchScript("script.py");
	nb++ ;
}

void MainWindow::truc()
{
	nb = 0 ;
	_time->start(400);
}